<?php

/**
 * Created by PhpStorm.
 * Author: ls
 * Time: 2022/1/28 9:29
 * Desc:
 */
abstract class Entities_Provider_Ticket_Order
{

    public function create($order, $ticket_api)
    {
        if ($order['api_channel_orderno']) {
            return array("status" => 0, "msg" => "已经创建订单了");
        }
        $params = self::set_order_request_params($order);
        $params['isPayed'] = 0;
        $rtn = $ticket_api->order_create($params);
        //远程下单成功.
        if ($rtn['code'] == 200) {
            $db = Database::instance();
            $db->begin();
            try {
                $updateData = array('api_channel_orderno' => $rtn['data']['platOrderId']);
                if (isset($rtn['data']['orderState'])) {
                    if ($rtn['data']['orderState'] == 0) {
                        // 待确认
                        if ($order['status'] == 1) {
                            // 切换为待确认
                            $updateData['status'] = 0;
                        }
                    } else if ($rtn['data']['orderState'] == 1) {
                        // 待支付 已成功
                        if ($order['status'] == 0) {
                            // 切换为待待支付
                            $updateData['status'] = 1;
                        }
                    }
                }
                //更新CMS订单远程订单号
                DB::update('member_order')->set($updateData)->where('id', '=', $order['id'])->execute();
                $order['api_channel_orderno'] = $rtn['data']['platOrderId'];
                $db->commit();
                return array("status" => 1, "msg" => "远程订单创建执行成功", 'order' => $order);
            } catch (Exception $e) {
                $db->rollback();
                return array("status" => 0, "msg" => $e->getMessage());
            }
        } else {
            // 创建远程订单失败 执行订单取消
            $cancelReason = isset($rtn['msg']) ? $rtn['msg'] : '远程下单失败';
            self::cancel_submit($order['ordersn'], $cancelReason);
            return array("status" => 0, "msg" => "执行失败");
        }
    }

    public function pay($order, $ticket_api)
    {
        if ($order['status'] != 2) {
            exit(json_encode(["status" => 0, "msg" => "订单状态错误"]));
        }
        if (!$order['api_channel_orderno']) {
            return array("status" => 0, "msg" => "未创建远程订单");
        }
        // 开始执行订单支付
        $params = array(
            'platOrderId' => $order['api_channel_orderno'],
            'partnerOrderId' => $order['ordersn'],
        );
        $rtn = $ticket_api->order_pay($params);
        if (isset($rtn['code']) && $rtn['code'] == 200) {
            $result = array("status" => 1, "msg" => "远程支付成功");
        } else {
            // 支付失败进行退款操作
            $total_info = Model_Member_Order_Compute::get_order_price($order['id']);
            if ($total_info && !empty($total_info['total_price'])) {
                self::refund_submit('allow', $order['ordersn'], 0, $rtn['msg']);
            }
            $result = array("status" => 0, "msg" => "远程支付失败");
        }
        return $result;
    }

    public function cancel($order, $ticket_api)
    {
        if (!$order['api_channel_orderno']) {
            return array("status" => 0, "msg" => "未创建订单");
        }
        if ($order['status'] != 3) {
            return array("status" => 0, "msg" => "订单状态错误");
        }
        // 开始执行订单支付
        $params = array(
            'platOrderId' => $order['api_channel_orderno'],
            'partnerOrderId' => $order['ordersn'],
        );
        $rtn = $ticket_api->order_cancel($params);
        if (isset($rtn['code']) && $rtn['code'] == 200) {
            $result = array("status" => 1, "msg" => "远程取消订单成功");
        } else {
            $result = array("status" => 0, "msg" => "远程取消订单失败");
        }
        return $result;
    }

    public function refund($order, $ticket_api)
    {
        $db = Database::instance();
        $db->begin();
        try {
            if (!$order['api_channel_orderno']) {
                throw new Exception('未创建订单');
            }
            if ($order['status'] != 6) {
                throw new Exception('订单状态错误');
            }
            $refund_info = DB::select()->from('member_order_refund')
                ->where('ordersn', '=', $order['ordersn'])
                ->order_by('addtime', 'desc')
                ->execute()
                ->current();
            $voucherList = array();
            $refund_order = array(
                'order_id' => $order['id'],
                'remote_order_id' => $order['api_channel_orderno'],
                'sn' => self::generateSn(),
                'voucher_list' => json_encode($voucherList),
                'refund_price' => $refund_info['refund_fee'],
                'refund_quantity' => $order['dingnum'],
                'unit_price' => $order['price'],
                'fee' => 0,
                'status' => 601,
                'addtime' => time()
            );
            //请求api退款
            $request_params = array(
                'partnerRefundId' => $refund_order['sn'],
                'platOrderId' => $order['api_channel_orderno'],
                'partnerOrderId' => $order['ordersn'],
                'voucherList' => $voucherList,
                'refundQuantity' => $order['dingnum'],
                'unitPrice' => $order['price'],
                'refundPrice' => $refund_order['refund_price'],
                'refundFee' => $refund_order['fee'],
                'refundTime' => $refund_order['addtime']
            );
            $rtn = $ticket_api->order_refund($request_params);
            if ($rtn['code'] != 200) {
                if ($rtn['code'] != 602) {
                    // 退款申请失败
                    DB::update('member_order')->set(array('status' => 2))->where('id', '=', $order['id'])->execute();
                    $originalStatus = $order['status'];
                    $order['status'] = 2;
                    Model_Member_Order::back_order_status_changed($originalStatus, $order, 'Model_Spot');
                    throw new Exception($rtn['msg']);
                } else {
                    // 退款申请成功 等待审核
                    $result = array("status" => 1, "msg" => "退款申请成功,等待审核");
                }
            } else {
                // 退单直接完成进行退款操作
                $total_info = Model_Member_Order_Compute::get_order_price($order['id']);
                if ($total_info && !empty($total_info['total_price'])) {
                    self::refund_submit('allow', $order['ordersn'], $total_info['pay_price'], $rtn['msg']);
                }
                $result = array("status" => 1, "msg" => "执行成功");
            }
        } catch (Exception $ex) {
            $db->rollback();
            $result = array("status" => 0, "msg" => "执行失败" . $ex->getMessage());
        }
        return $result;
    }

    public function query($order, $ticket_api)
    {
        $request_params = array(
            'platOrderId' => $order['api_channel_orderno'],
            'partnerOrderId' => $order['ordersn'],
        );
        $rtn = $ticket_api->order_query($request_params);
        if ($rtn['code'] == 200) {
            $result = array("status" => 1, "msg" => "查询成功", 'data'=> $rtn['data']);
        }else{
            $result = array("status" => 0, "msg" => "查询失败");
        }
        return $result;
    }

    /**
     * 设置订单创建的请求参数
     * @param $order
     * @return array
     */
    public static function set_order_request_params($order)
    {
        // 获取报价信息
        $price = Model_Spot_Ticket_Price::current_price($order['suitid'], strtotime($order['usedate']));
        // 联系人信息
        $linkman = $order['linkman'];
        $linktel = $order['linktel'];
        $linkidcard = $order['linkidcard'] ? $order['linkidcard'] : '0';
        $visitors = self::set_order_visitors($order['id']);
        if (!$linkman && isset($visitors[0]['name'])) {
            $linkman = $visitors[0]['name'];
            $linktel = $visitors[0]['mobile'];
        }
        if (!$linkman) {
            exit(json_encode(array("status" => 0, "msg" => "联系人信息为空")));
        }
        $params = array(
            'productId' => $order['provider_product_id'],
            'orderId' => $order['ordersn'],
            'buyPrice' => $price['adultbasicprice'],
            'unitPrice' => $price['adultprice'],
            'totalPrice' => $order['totalprice'],
            'linkman' => $linkman,
            'linkMobile' => $linktel,
            'linkCardNumber' => $linkidcard,
            'quantity' => $order['dingnum'],
            'travelDate' => $order['usedate'],
            'visitors' => $visitors ? $visitors : array()
        );
        if (!empty($tourername)) $params['tourname'] = $tourername;
        if (!empty($idcard)) $params['idcard'] = $idcard;
        return $params;
    }

    /**
     * 设置订单游客
     */
    public static function set_order_visitors($orderId)
    {
        $tourer = Model_Member_Order_Tourer::get_tourer_by_orderid($orderId);
        $visitors = array();
        foreach ($tourer as $v) {
            $visitor = array();
            $visitor['name'] = $v['tourername'];
            if ($v['mobile']) {
                $visitor['mobile'] = $v['mobile'];
            }
            if ($v['cardnumber']) {
                $visitor['credentials'] = json_encode(array('0' => $v['cardnumber']));
            }
            $visitors[] = $visitor;
            unset($visitor);
        }
        return $visitors;
    }

    /**
     * 门票订单取消
     * @param $ordersn
     * @param string $cancelReason
     * @return bool
     * @throws Kohana_Exception
     */
    private static function cancel_submit($ordersn, $cancelReason = '')
    {
        $m = ORM::factory('member_order')
            ->where('ordersn', '=', "{$ordersn}")
            ->and_where('status', 'in', array(0, 1))
            ->find();
        if ($m->loaded())
        {
            $orgstatus = $m->status;
            $m->status = 3;
            $m->close_reason = mb_substr($cancelReason, 0, 120);
            $m->update();
            if ($m->saved())
            {
                Model_Member_Order::back_order_status_changed($orgstatus,$m->as_array(),"Model_Spot");
            }
        }
        return true;
    }

    /**
     * 发起门票订单退款
     * @param $type
     * @param $ordersn
     * @param int $cancelMoney
     * @param string $message
     * @return bool
     */
    public static function refund_submit($type, $ordersn, $cancelMoney = 0, $message = '')
    {
        $order = Model_Member_Order::order_info($ordersn);
        if ($type == 'allow') {
            //订单总价信息
            $refund_cost = 0; // 退款手续费
            $total_info = Model_Member_Order_Compute::get_order_price($order['id']);
            if ($total_info && !empty($total_info['total_price']) && $cancelMoney > 0) {
                $refund_cost = $total_info['pay_price'] - doubleval($cancelMoney);
            }
            Pay_Online_Refund::refund_start($ordersn, 'Model_Spot', false, null, $refund_cost);
        } elseif ($type == 'back') {
            Pay_Online_Refund::admin_refund_back($ordersn, 'Model_Spot', $message);
        }
        return true;
    }

    /**
     * @return string 生成请求序列号
     */
    public static function generateSn()
    {
        $order_id_main = date('YmdHis') . rand(10000000, 99999999);
        $order_id_len = strlen($order_id_main);
        $order_id_sum = 0;
        for ($i = 0; $i < $order_id_len; $i++) {
            $order_id_sum += (int)(substr($order_id_main, $i, 1));
        }
        return $order_id_main . str_pad((100 - $order_id_sum % 100) % 100, 2, '0', STR_PAD_LEFT);
    }
}